from threading import Thread
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QPushButton, QMessageBox, QLineEdit, QVBoxLayout, QHBoxLayout, QPlainTextEdit, QLabel
from PyQt5 import QtWidgets as qtw
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtGui import QIcon
from random import randint


class ExecCmd(QThread):
    qt_singnal = pyqtSignal(str, str, int)

    def __init__(self, text=None, status_fun=None):
        super(ExecCmd, self).__init__(parent=None)
        self.text = text
        if status_fun:
            self.qt_singnal.connect(status_fun)

    def __del__(self):
        self.wait()
        print("exit thread: {}".format(self.thread))

    def run(self):
        try:
            r = eval(self.text, {}, {})
            self.qt_singnal.emit(
                "command successfully executed, return value: {}".format(r), "green", 10000)
        except SyntaxError:
            try:
                exec(self.text, {}, {})
                self.qt_singnal.emit(
                    "command successfully executed", "green", 10000)
            except Exception as e:
                self.qt_singnal.emit("Failed: {}".format(e), "red", 10000)
        except Exception as e:
            self.qt_singnal.emit("Failed: {}".format(e), "red", 10000)


class Example(QMainWindow):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        self.setGeometry(300, 300, 800, 600)
        self.setWindowTitle('Python Command')
        self.setWindowIcon(QIcon('xdbcb8.ico'))

        lbl = QLabel("Editor")
        hbox = QHBoxLayout()
        hbox.addWidget(lbl)
        hbox.addStretch(1)
        btn_connect0 = QPushButton("connect real")
        btn_connect1 = QPushButton("connect sim")
        btn_connect0.clicked.connect(lambda: self.connectRobot(False))
        btn_connect1.clicked.connect(lambda: self.connectRobot(True))
        hbox.addWidget(btn_connect0)
        hbox.addWidget(btn_connect1)

        vbox = QVBoxLayout()
        vbox.addLayout(hbox)

        editor = QPlainTextEdit()
        vbox.addWidget(editor)
        self.editor = editor

        bt_clear = QPushButton("clear")
        bt_run = QPushButton('Run')
        bt_clear.clicked.connect(self.editor.clear)
        bt_run.clicked.connect(lambda: ExecCmd(
            self.editor.toPlainText(), self.setStatusMsg).start())
        check_box = qtw.QCheckBox("Simulation")

        hbox1 = QHBoxLayout()
        hbox1.addWidget(bt_clear)
        hbox1.addStretch(1)
        hbox1.addWidget(check_box)
        hbox1.addWidget(bt_run)
        vbox.addLayout(hbox1)

        self.setCentralWidget(QWidget())
        self.centralWidget().setLayout(vbox)

        status_bar: qtw.QStatusBar = self.statusBar()
        self.status_lbl = QLabel("<b>Status</b>")
        status_bar.addPermanentWidget(self.status_lbl)
        self.setStatusMsg("ready")
        self.show()

    def setStatusMsg(self, msg, color="green", duration=10000):
        self.status_lbl.setStyleSheet("color:{}".format(color))
        self.statusBar().showMessage("{}".format((msg)), duration)

    def connectRobot(self, simulation=True):
        self.setStatusMsg("Undering developping!")

    def closeEvent(self, event):

        reply = QMessageBox.question(
            self, 'Ensure', 'Sure to quit?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
